import { RouteRecordRaw } from 'vue-router';
import { storeToRefs } from 'pinia';
import pinia from '/@/stores/index';
import { useUserInfo } from '/@/stores/userInfo';
import { useRequestOldRoutes } from '/@/stores/requestOldRoutes';
import { Session } from '/@/utils/storage';
import { NextLoading } from '/@/utils/loading';
import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route';
import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '/@/router/index';
import { useRoutesList } from '/@/stores/routesList';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { useMenuApi } from '/@/api/url/index';

// 后端控制路由

// 引入菜单 api 请求接口
const menuApi = useMenuApi();

/**
 * 获取目录下的 .vue、.tsx 全部文件
 * @method import.meta.glob
 * @link 参考：https://cn.vitejs.dev/guide/features.html#json
 */
const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}');
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}');
const dynamicViewsModules: Record<string, Function> = Object.assign({}, { ...layouModules }, { ...viewsModules });

/**
 * 后端控制路由：初始化方法，防止刷新时路由丢失
 * @method NextLoading 界面 loading 动画开始执行
 * @method useUserInfo().setUserInfos() 触发初始化用户信息 pinia
 * @method useRequestOldRoutes().setRequestOldRoutes() 存储接口原始路由（未处理component），根据需求选择使用
 * @method setAddRoute 添加动态路由
 * @method setFilterMenuAndCacheTagsViewRoutes 设置路由到 pinia routesList 中（已处理成多级嵌套路由）及缓存多级 */
export async function initBackEndControlRoutes() {
	if (window.nextLoading === undefined) {
		NextLoading.start();
	}
	try {
		const userInfoStore = useUserInfo(pinia);
		await userInfoStore.$hydrate();
		// 断言 res 为包含 path 和 children 的数组
		const res = userInfoStore.menuList as Array<{
			path: string;
			children?: Array<{ path: string; children?: any[] }>;
		}>;
		// 先判断 res 是否为有效数组
		if (!Array.isArray(res) || res.length <= 0) {
			NextLoading.done();
			return true;
		}
		// 提取后端返回的第一个有效路由路径
		let defaultRoutePath = '';
		if (res.length > 0) {
			const firstMenu = res[0];
			// 直接访问属性
			defaultRoutePath = firstMenu.children && firstMenu.children.length > 0
				? firstMenu.children[0].path
				: firstMenu.path;
		}
		useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res)));
		const filteredRoutes = await filterRoutes(res, dynamicRoutes[0].children);
		dynamicRoutes[0].children = filteredRoutes;
		// 给根路由动态设置 redirect
		dynamicRoutes[0].redirect = defaultRoutePath;
		const rootRoute = router.getRoutes().find(route => route.path === '/');
		if (rootRoute?.name) {
			router.removeRoute(rootRoute.name);
		}
		await setAddRoute();
		setFilterMenuAndCacheTagsViewRoutes();
		NextLoading.done();
		return false;
	} catch (error) {
		console.error('后端路由初始化失败:', error);
		NextLoading.done();
		return true;
	}
}
/**
 * 设置路由到pinia及缓存
 */
export async function setFilterMenuAndCacheTagsViewRoutes() {
	const storesRoutesList = useRoutesList(pinia);
	storesRoutesList.setRoutesList(dynamicRoutes[0].children as any);
	setCacheTagsViewRoutes();
}

/**
 * 缓存多级嵌套数组处理后的一维数组
 */
export function setCacheTagsViewRoutes() {
	const storesTagsView = useTagsViewRoutes(pinia);
	const flattenedRoutes = formatFlatteningRoutes(dynamicRoutes);
	const twoStageRoutes = formatTwoStageRoutes(flattenedRoutes);
	const tagsViewRoutes = twoStageRoutes[0].children;
	storesTagsView.setTagsViewRoutes(tagsViewRoutes);
}

/**
 * 处理路由格式及添加404路由
 */
export function setFilterRouteEnd() {
	let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
	// 添加404等路由
	filterRouteEnd[0].children = [...filterRouteEnd[0].children, ...notFoundAndNoPower];
	return filterRouteEnd;
}

/**
 * 添加动态路由
 */
export async function setAddRoute() {
	const routesToAdd = setFilterRouteEnd();
	routesToAdd.forEach((route: RouteRecordRaw) => {
		// 检查路由是否已存在
		const exists = router.hasRoute(route.name!);
		if (exists) {
			return;
		}
		router.addRoute(route);
	});
}

/**
 * 请求后端路由菜单接口
 */
export function getBackEndControlRoutes() {
	const stores = useUserInfo(pinia);
	const { menuList } = storeToRefs(stores);
	return menuList.value;
}

/**
 * 重新请求后端路由菜单接口
 */
export async function setBackEndControlRefreshRoutes() {
	const newRoutes = await getBackEndControlRoutes();
	return newRoutes;
}

/**
 * 后端路由component转换
 * @param routes 后端返回的路由表数组
 * @returns 返回处理成函数后的component
 */
export function backEndComponent(routes: any) {
	if (!routes) {
		return;
	}
	return routes.map((item: any) => {
		if (item.component) {
			item.component = dynamicImport(dynamicViewsModules, item.component as string);
		}
		if (item.children && item.children.length > 0) {
			item.children = backEndComponent(item.children);
		}
		return item;
	});
}
/**
 * 对比路由
 * @param menu 后端返回的路由表数组
 * @param routes 本地路由表数组
 * @returns 返回可访问数组
 */
export function filterRoutes(menu: any, routes: any) {
	let canRoutes: any = [];
	// 标记是否已给第一个路由添加不可关闭
	let isFirstRoute = true;
	menu.forEach((item: any) => {
		routes.forEach((route: any) => {
			if (item.path === route.path) {
				if (item.children && item.children.length > 0) {
					item.children = filterRoutes(item.children, routes);
				}
				// 合并meta信息
				route.meta.icon = item.icon;
				route.meta.title = item.title || '';
				//给第一个匹配成功的路由添加 isAffix: true
				if (isFirstRoute) {
					route.meta.isAffix = true; // 标记为不可关闭
					isFirstRoute = false; // 后续路由不再添加
				} else {
					// 其他路由强制设为可关闭、
					route.meta.isAffix = false;
				}

				canRoutes.push({ ...route });
			}
		});
	});
	return canRoutes;
}

/**
 * 后端路由component转换函数
 */
export function dynamicImport(dynamicViewsModules: Record<string, Function>, component: string) {
	const keys = Object.keys(dynamicViewsModules);
	const matchKeys = keys.filter((key) => {
		const k = key.replace(/..\/views|../, '');
		const match = k.startsWith(`${component}`) || k.startsWith(`/${component}`);
		return match;
	});

	if (matchKeys?.length === 1) {
		const matchKey = matchKeys[0];
		return dynamicViewsModules[matchKey];
	}
	if (matchKeys?.length > 1) {
		console.error(`找到多个匹配组件: ${matchKeys.join(', ')}`);
		return false;
	}
	console.error(`未找到匹配组件: ${component}`);
}